<?php

set_time_limit(0);
ini_set('memory_limit', '2048M');
//获取url
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_WARNING);
$url = trim($_POST['url']);
//获取请求方式
$http = trim($_POST['http']);
//根据不同的请求方式发请求
unset($_POST['url']);
unset($_POST['http']);


if ($http == 'get') {
    header("Content-type: text/html; charset=utf-8");
    $res = Http::get($url, $_POST);
    echo $res;
    exit;
}

if ($http == 'post') {
    header("Content-type: text/html; charset=utf-8");
    $res = Http::post($url, $_POST);
    echo $res;
    exit;
}

class Http {

    //模拟post请求
    public static function post($url, $data) {
        $ch = curl_init();
//        $des = new EncryptClass();
//        foreach ($data as $key => $val) {
//            $data[$key] = $des->encrypt($val);
//        }

        //如果有上传的文件
        if (count($_FILES) != 0) {
            $tmp_filename = $_FILES['upload']['name']; //暂时保存临时图片到本地
            move_uploaded_file($_FILES['upload']['tmp_name'], $tmp_filename);
            $data['file'] = "@{$tmp_filename}" . ";type={$_FILES['upload']['type']}"; //转发图片
        }

        $url = self::buildUrl($url);

//        if ($data['userId']) {
//            $url = $url . "&userId=" . urlencode($data['userId']);
//            unset($data['userId']);
//        }
        if (!extension_loaded('curl')) {
            exit('you must open the curl module');
        }
         
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_URL, $url);
        $response = curl_exec($ch);
        curl_close($ch);

        if (isset($tmp_filename)) {
            @unlink($tmp_filename); //上传后删除临时文件
        }

//        $decresponse = $des->decrypt($response);
//        if ($decresponse == false) {
//            var_dump($response);
//            exit();
//        }
//        $response = json_decode($response, true);

        return $response;
    }

    //模拟get请求
    public static function get($url, $data) {
        $url = self::buildUrl($url);
        $des = new EncryptClass();
        foreach ($data as $key => $value) {
            if ($value) {
                $url = $url . '&' . $key . '=' . urlencode($des->encrypt(strval($value)));
//                $url = $url . '/' . $key . '/' . urlencode(strval($value));
            }
        }
        //$res = $des->encrypt(1);

        $res = file_get_contents($url);

        $decrres = $des->decrypt($res);
        if ($decrres == false) {
            var_dump($res);
            exit();
        }
//        $res = json_decode($res, true);

        return $decrres;
    }

    public static function buildUrl($url) {
     

        //$url = 'http://zhenhuiwan.localhost.com/' . $url . '&aid=' . $aid . '&t=' . urlencode($t);
       

        $url = 'http://rpgmini.local.gjgj.com' . $url ;
        return $url;
    }

}

class EncryptClass {

    /**
     * 加解密密钥
     */
    static $defultKey = 'houwan123';

    /**
     * 加密函数
     * 
     * @param $string 加密串            
     * @param $key 密匙            
     * @param $expiry 有效期            
     * @return 加密串
     */
    function ecode($string, $key = '', $expiry = 0) {
        $result = self::_authcode($string, 'ECODE', $key, $expiry);
        $result = str_replace('/', '.', $result);
        return $result;
    }

    /**
     * 解密函数
     * 
     * @param $string 解密串            
     * @param $key 密匙            
     * @param $expiry 有效期            
     * @return 解密串
     */
    function decode($string, $key = '', $expiry = 0) {
        $string = str_replace('.', '/', $string);
        $result = self::_authcode($string, 'DECODE', $key, $expiry);

        return $result;
    }

    /**
     * discuz加密解密函数
     * 
     * @access private
     * @param $string 加密串            
     * @param $operation DECODE表示解密,其它表示加密            
     * @param $key 密匙            
     * @param $expiry 密文有效期            
     * @return 加密或解密串
     */
    private function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
        // 动态密匙长度，相同的明文会生成不同密文就是依靠动态密匙
        $ckey_length = 2;

        // 密匙
        $key = md5($key ? $key : self::$defultKey);

        // 密匙a会参与加解密
        $keya = md5(substr($key, 0, 16));
        // 密匙b会用来做数据完整性验证
        $keyb = md5(substr($key, 16, 16));
        // 密匙c用于变化生成的密文
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), - $ckey_length)) : '';
        // 参与运算的密匙
        $cryptkey = $keya . md5($keya . $keyc);
        $key_length = strlen($cryptkey);
        // 明文，前10位用来保存时间戳，解密时验证数据有效性，10到26位用来保存$keyb(密匙b)，解密时会通过这个密匙验证数据完整性
        // 如果是解码的话，会从第$ckey_length位开始，因为密文前$ckey_length位保存 动态密匙，以保证解密正确
        $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
        $string_length = strlen($string);
        $result = '';
        $box = range(0, 255);
        $rndkey = array();
        // 产生密匙簿
        for ($i = 0; $i <= 255; $i ++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }
        // 用固定的算法，打乱密匙簿，增加随机性，好像很复杂，实际上并不会增加密文的强度
        for ($j = $i = 0; $i < 256; $i ++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
        // 核心加解密部分
        for ($a = $j = $i = 0; $i < $string_length; $i ++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            // 从密匙簿得出密匙进行异或，再转成字符
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }
        if ($operation == 'DECODE') {
            // substr($result, 0, 10) == 0 验证数据有效性
            // substr($result, 0, 10) - time() > 0 验证数据有效性
            // substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
            // 验证数据有效性，请看未加密明文的格式
            if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
                return substr($result, 26);
            } else {
                return '';
            }
        } else {
            // 把动态密匙保存在密文里，这也是为什么同样的明文，生产不同密文后能解密的原因
            // 因为加密后的密文可能是一些特殊字符，复制过程可能会丢失，所以用base64编码
            return $keyc . str_replace('=', '', base64_encode($result));
        }
    }

    /**
     * des加密函数
     * 
     * @access public
     * @param $input 加密串            
     * @param $url 是否为url            
     * @return 加密串
     */
    public function encrypt($input, $url = false) {
        $input = trim(chop($input));
        $input = strtr($input, array(
            "\n" => '',
            "\t" => '',
            "\r" => ''
        ));
        $size = mcrypt_get_block_size('des', 'ecb');
        $input = self::pkcs5_pad($input, $size);
        $td = mcrypt_module_open('des', '', 'ecb', '');
        $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);

        @mcrypt_generic_init($td, self::$defultKey, $iv);

        $data = mcrypt_generic($td, $input);

        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);

        // $result = $url?urlencode(base64_encode($data)):base64_encode($data);
        $result = base64_encode($data);
//        $result = str_replace('/', '.', $result);
        return $result;
    }

    /**
     * des解密函数
     * 
     * @access public
     * @param $encrypted 解密串            
     * @param $url 是否为url            
     * @return 解密串
     */
    public function decrypt($encrypted, $url = false) {
//        $encrypted = str_replace('.', '/', $encrypted);
        // $encrypted = $url?urldecode($encrypted):$encrypted;
        $encrypted = base64_decode($encrypted);
        $td = mcrypt_module_open('des', '', 'ecb', ''); // 使用MCRYPT_DES算法,cbc模式
        $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        $ks = mcrypt_enc_get_key_size($td);
        @mcrypt_generic_init($td, self::$defultKey, $iv);
        $decrypted = mdecrypt_generic($td, $encrypted);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        return self::pkcs5_unpad($decrypted);
    }

    /**
     * pkcs5填充函数
     * 
     * @access private
     * @param $text 需要的字符串            
     * @param $blocksize 填充方式，块大小            
     * @return 填充的结果
     */
    private function pkcs5_pad($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    /**
     * pkcs5 填充解码函数
     * 
     * @access private
     * @param $text 需要pkcs5你填充的字符串            
     * @return 解码的结果
     *
     */
    private function pkcs5_unpad($text) {
        $pad = ord($text{strlen($text) - 1});
        if ($pad > strlen($text))
            return false;
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad)
            return false;
        return substr($text, 0, - 1 * $pad);
    }

}
